package com.xiyu.service.service.health;

import com.xiyu.service.vo.health.medicine.MedicineSingleGetOutput;
import com.xiyu.service.vo.health.medicine.MedicineUpdateInput;
import com.xiyu.service.vo.health.medicine.MedicineGetOutput;
import com.xiyu.service.vo.health.medicine.MedicineCreateInput;
import com.xiyu.service.model.medicine.HealthMedicine;
import com.xiyu.service.repository.medicine.HealthMedicineRepository;
import com.xiyu.service.vo.health.medicine.MedicinePageQueryOutput;
import com.xiyu.service.vo.health.medicine.MedicinePageQueryInput;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.babyfish.jimmer.Page;
import java.util.*;

import org.springframework.transaction.annotation.Transactional;
import com.xiyu.service.framework.web.web.core.pojo.PageResult;
import com.xiyu.service.convert.health.MedicineConvert;

import static com.xiyu.service.framework.exception.util.ServiceExceptionUtil.exception;
import static com.xiyu.service.errorCode.health.MedicineErrorCode.*;

/**
 * 药品档案 Service 实现类
 */
@Service
@Validated
public class MedicineServiceImpl implements MedicineService {

    @Resource
    private HealthMedicineRepository healthMedicineRepository;


    @Override
    public PageResult<MedicinePageQueryOutput> pageQuery(MedicinePageQueryInput inputVO) {
        Page<HealthMedicine> pageHealthMedicine = healthMedicineRepository.pageQuery(inputVO);
        List<MedicinePageQueryOutput> listHealthMedicine = MedicineConvert.INSTANCE.pageQueryOutputConvert(pageHealthMedicine.getRows());
        return new PageResult<>(listHealthMedicine, pageHealthMedicine.getTotalRowCount());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long create(MedicineCreateInput inputVO) {
        Optional<HealthMedicine> optionalDuplicateHealthMedicine = healthMedicineRepository.findFirstByMedicineName(inputVO.getMedicineName());
        if(optionalDuplicateHealthMedicine.isPresent()){
            throw exception(HEALTH_MEDICINE_NAME_DUPLICATE);
        }
        HealthMedicine newHealthMedicine = MedicineConvert.INSTANCE.createInputConvert(inputVO);
        newHealthMedicine = healthMedicineRepository.insert(newHealthMedicine);
        return newHealthMedicine.id();

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(MedicineUpdateInput inputVO) {
        Optional<HealthMedicine> optionalDuplicateHealthMedicine = healthMedicineRepository.findFirstByMedicineName(inputVO.getMedicineName());
        if(optionalDuplicateHealthMedicine.isPresent() && !inputVO.getId().equals(optionalDuplicateHealthMedicine.get().id())){
            throw exception(HEALTH_MEDICINE_NAME_DUPLICATE);
        }
        Optional<HealthMedicine> optionalOldHealthMedicine = healthMedicineRepository.findById(inputVO.getId());
        if(!optionalOldHealthMedicine.isPresent()){
            throw exception(HEALTH_MEDICINE_NOT_EXIST);
        }
        HealthMedicine updateHealthMedicine = MedicineConvert.INSTANCE.updateInputConvert(inputVO);
        healthMedicineRepository.update(updateHealthMedicine);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleted(Long id) {
        Optional<HealthMedicine> optionalDeleteHealthMedicine = healthMedicineRepository.findById(id);
        if(!optionalDeleteHealthMedicine.isPresent()){
            throw exception(HEALTH_MEDICINE_NOT_EXIST);
        }
        return true;
    }

    @Override
    public MedicineGetOutput get(Long id) {
        Optional<HealthMedicine> optionalHealthMedicine = healthMedicineRepository.findById(id);
        if(!optionalHealthMedicine.isPresent()){
            throw exception(HEALTH_MEDICINE_NOT_EXIST);
        }
        return MedicineConvert.INSTANCE.getOutputConvert(optionalHealthMedicine.get());
    }

    @Override
    public MedicineSingleGetOutput singleGet(Long id) {
        Optional<HealthMedicine> optionHealthMedicine = healthMedicineRepository.findById(id);
        if(!optionHealthMedicine.isPresent()){
            throw exception(HEALTH_MEDICINE_NOT_EXIST);
        }
        return MedicineConvert.INSTANCE.singleGetOutputConvert(optionHealthMedicine.get());

    }

}
